/*
 * Context.cpp
 *
 * 28 de novembro de 2008
 */
#include "Context.h"

#include <cstdlib>
#include <iostream>

#include <math.h>
#include <allegro.h>
#include <exception>
#include <vector>

#include "defs.h"
#include "util.h"
#include "AllegroException.h"
#include "Synchronizer.h"

using std::vector;

using namespace core;

Context* Context::_instance = NULL;

Context::Context() {
	_synchronizer = new Synchronizer(*this);
	_metrics.centre(25, 25);
	_metrics.zoom(20.0);
}

Context::~Context() {
	delete _synchronizer;
}

void Context::synch(float const& past_seconds) {
	Point p;

	if (key[KEY_ESC]) {
		_synchronizer->stop();
		return;
	}
	_metrics.update();
	clear_bitmap(_buffer);

	vector<Vertex>::iterator iter;
	for (iter = _surface.begin(); iter != _surface.end(); ++iter) {
		_metrics.toScreen(*iter, p);
		putpixel(_buffer,
				(int) floor(p.x),
				(int) floor(p.y),
				makecol(255, 255, 255));
		//std::cout << p.x << "," << p.y << std::endl;
		//std::cout << (*iter).x << "," << (*iter).y << std::endl;
		//_synchronizer->stop();
	}

	blit(_buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
}

Context* Context::instance() {
	if (_instance == NULL) {
		_instance = new Context();
	}
	return _instance;
}

void Context::build_allegro() throw(AllegroException) {
	int err = 0;

	if ((err = allegro_init()) != 0) {
		throw AllegroException(allegro_error);
	}

	if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0) != 0) {
		if ((err = set_gfx_mode(GFX_SAFE, 320, 200, 0, 0)) != 0) {
			throw AllegroException(err);
		}
	}

	install_timer();
	install_keyboard();
	install_mouse();

	_buffer = create_bitmap(SCREEN_W, SCREEN_H);
}

void Context::destroy_allegro() throw(AllegroException) {
	destroy_bitmap(_buffer);
}

Synchronizer& Context::synchronizer() {
	return *_synchronizer;
}

vector<Vertex>& Context::surface() {
	return _surface;
}

void Context::load_surface(std::string filename) {
	int x, y;
	Vertex* v;

	for (x = 0; x <= 50; x++) {
		for (y = 0; y <= 50; y++) {
			v = new Vertex(x, y, 0);
			_surface.push_back(*v);
		}
	}
	/*
	 map<const string, string> data;
	 util::load_map(data, filename);

	 map<const string, string>::iterator iter;
	 for (iter = data.begin(); iter != data.end(); ++iter) {
	 std::cout << iter->first << " = " << iter->second << std::endl;
	 }
	 */
}

void unexpected_exception() {
	throw Exception("Unexpected exception");
}

int main() {
	Context* main = NULL;
	int ret = EXIT_SUCCESS;

	std::set_unexpected(unexpected_exception);

	try {
		main = Context::instance();
		main->build_allegro();

		main->load_surface("...");

		main->synchronizer().run();
		main->destroy_allegro();

	} catch (Exception& ex) {
		std::cerr << ex.what() << std::endl;
		ret = EXIT_FAILURE;
	}
	delete main;
	return ret;
}
END_OF_MAIN()
